﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OperGui.Models;
using System.Xml;
using System.IO;
using System.Windows.Resources;
using System.Windows;
using System.Xml.Linq;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Data.Linq;
using OperGui.ViewModel;
using VI.Fsc.OperatorGui.Models.Fsc.Configuration;
using VI.Fsc.Common.Fsc;
using System.Data;

namespace OperGui
{
    public class DataDispacher
    {
        #region fields
        private Dictionary<string, ExtendedStructureItem> structureTree;
        // private ObservableCollection<Model> sectionViewData;
        static ObservableCollection<CStructureItem> errors;
        static DataDispacher instance;
        static List<ExtendedStructureItem> StructureList;
        public string resourceFile = "Data/CSTMS.xml";
        public string OpcItems = "Data/OpcItems.xml";
        public delegate void errorUpdateEventHandler();
        public event errorUpdateEventHandler errorUpdateEvent;
        // static valuepair _index;
        #endregion

        //Constructor
        protected DataDispacher()
        {
            errors = new ObservableCollection<CStructureItem>();
            StructureList = new List<ExtendedStructureItem>();

            initializedstructure("Data/CSTMS.xml", "Data/OpcItems.xml");
            XmlConfigReader reader = new XmlConfigReader();
        }

        //Initial data for testing
        /* static void initializedErrorsList()
         {
             #region initial errors
             Dictionary<string, object> row = new Dictionary<string, object>();
             row.Add("Location", "GrandParentName");
             row.Add("Section", "ParentName");
             row.Add("CustomSection", "sectionTranslation.GetTranslation(ParentName)");
             row.Add("Status", "Status");
             row.Add("ElementName", "DisplayName");
             row.Add("ElementShortId", "ShortId");
             row.Add("Timestamp", "ErrorTime");
             row.Add("ElementId", "Id");
             row.Add("ProblemKey", "ProblemKey");
             row.Add("SolutionKey", "ProblemKey");
             row.Add("SortId", "Id");
             row.Add("Updated", "true");
             row.Add("RawAreaId", "RawAreaId");
             row.Add("RawZoneId", "Zone3");
             row.Add("RawSectionId", "RawSectionId");
             row.Add("MarkCode", "MarkCode");
             row.Add("ExtendedId", "ExtendedId");
             row.Add("Type", "Type");
             errors.Add(row);
             row = new Dictionary<string, object>();
             row.Add("Location", "GrandParentName1");
             row.Add("Section", "ParentName1");
             row.Add("CustomSection", "sectionTranslation.GetTranslation(ParentName)11");
             row.Add("Status", "Status1");
             row.Add("ElementName", "DisplayName1");
             row.Add("ElementShortId", "ShortId1");
             row.Add("Timestamp", "ErrorTime1");
             row.Add("ElementId", "Id1");
             row.Add("ProblemKey", "ProblemKey1");
             row.Add("SolutionKey", "ProblemKey1");
             row.Add("SortId", "Id1");
             row.Add("Updated", "true");
             row.Add("RawAreaId", "RawAreaId1");
             row.Add("RawZoneId", "Zone1");
             row.Add("RawSectionId", "RawSectionId1");
             row.Add("MarkCode", "MarkCode1");
             row.Add("ExtendedId", "ExtendedId1");
             row.Add("Type", "Type1");
             errors.Add(row);
             row = new Dictionary<string, object>();
             row.Add("Location", "GrandParentName2");
             row.Add("Section", "ParentName2");
             row.Add("CustomSection", "sectionTranslation.GetTranslation(ParentName)2");
             row.Add("Status", "Status2");
             row.Add("ElementName", "DisplayName2");
             row.Add("ElementShortId", "ShortId2");
             row.Add("Timestamp", "ErrorTime2");
             row.Add("ElementId", "Id2");
             row.Add("ProblemKey", "ProblemKey2");
             row.Add("SolutionKey", "ProblemKey2");
             row.Add("SortId", "Id2");
             row.Add("Updated", "true");
             row.Add("RawAreaId", "RawAreaId2");
             row.Add("RawZoneId", "Zone2");
             row.Add("RawSectionId", "RawSectionId2");
             row.Add("MarkCode", "MarkCode2");
             row.Add("ExtendedId", "ExtendedId2");
             row.Add("Type", "Type2");
             errors.Add(row);
             row = new Dictionary<string, object>();
             row.Add("Location", "GrandParentName2");
             row.Add("Section", "ParentName2");
             row.Add("CustomSection", "sectionTranslation.GetTranslation(ParentName)2");
             row.Add("Status", "Status2");
             row.Add("ElementName", "DisplayName2");
             row.Add("ElementShortId", "ShortId2");
             row.Add("Timestamp", "ErrorTime2");
             row.Add("ElementId", "Id2");
             row.Add("ProblemKey", "ProblemKey2");
             row.Add("SolutionKey", "ProblemKey2");
             row.Add("SortId", "Id2");
             row.Add("Updated", "true");
             row.Add("RawAreaId", "RawAreaId2");
             row.Add("RawZoneId", "Zone2");
             row.Add("RawSectionId", "RawSectionId2");
             row.Add("MarkCode", "MarkCode2");
             row.Add("ExtendedId", "ExtendedId2");
             row.Add("Type", "Type2");
             errors.Add(row);
             row = new Dictionary<string, object>();
             row.Add("Location", "GrandParentName2");
             row.Add("Section", "ParentName2");
             row.Add("CustomSection", "sectionTranslation.GetTranslation(ParentName)2");
             row.Add("Status", "Status2");
             row.Add("ElementName", "DisplayName2");
             row.Add("ElementShortId", "ShortId2");
             row.Add("Timestamp", "ErrorTime2");
             row.Add("ElementId", "Id2");
             row.Add("ProblemKey", "ProblemKey2");
             row.Add("SolutionKey", "ProblemKey2");
             row.Add("SortId", "Id2");
             row.Add("Updated", "true");
             row.Add("RawAreaId", "RawAreaId2");
             row.Add("RawZoneId", "Zone2");
             row.Add("RawSectionId", "RawSectionId2");
             row.Add("MarkCode", "MarkCode2");
             row.Add("ExtendedId", "ExtendedId2");
             row.Add("Type", "Type2");
             errors.Add(row);
             row = new Dictionary<string, object>();
             row.Add("Location", "GrandParentName2");
             row.Add("Section", "ParentName2");
             row.Add("CustomSection", "sectionTranslation.GetTranslation(ParentName)2");
             row.Add("Status", "Status2");
             row.Add("ElementName", "DisplayName2");
             row.Add("ElementShortId", "ShortId2");
             row.Add("Timestamp", "ErrorTime2");
             row.Add("ElementId", "Id2");
             row.Add("ProblemKey", "ProblemKey2");
             row.Add("SolutionKey", "ProblemKey2");
             row.Add("SortId", "Id2");
             row.Add("Updated", "true");
             row.Add("RawAreaId", "RawAreaId2");
             row.Add("RawZoneId", "Zone1");
             row.Add("RawSectionId", "RawSectionId2");
             row.Add("MarkCode", "MarkCode2");
             row.Add("ExtendedId", "ExtendedId2");
             row.Add("Type", "Type2");
             errors.Add(row);
             #endregion
         }*/


        static void initializedstructure(string resourceFile, string OpcItems)
        {

            //Group
            using (Stream stream = GetResourceStream(resourceFile))
            using (XmlReader xmlRdr = new XmlTextReader(stream))
            {

                XDocument doc = XDocument.Load(xmlRdr);

                var group = doc.Descendants("Group");


                foreach (var Group in group)
                {
                    StructureList.Add(new ExtendedStructureItem(Group.Attribute("ID").Value.ToString(), "Group", null, Group.Attribute("CName").Value.ToString()));

                    var child = Group.Descendants("Child");

                    if (child != null)
                    {
                        foreach (var Child in child)
                        {
                            StructureList.Add(new ExtendedStructureItem(Child.Attribute("ID").Value.ToString(), Group.Attribute("ID").Value.ToString(), null, Child.Attribute("CName").Value.ToString()));
                        }
                    }
                }
            }
            //Zone
            using (Stream stream = GetResourceStream(OpcItems))
            using (XmlReader xmlRdr = new XmlTextReader(stream))
            {

                XDocument doc = XDocument.Load(xmlRdr);

                var item = doc.Descendants("Item");


                foreach (var Item in item)
                {

                    if (Item.Attribute("Type").Value.ToString() == "component")
                    {
                        string parentName = Item.Attribute("Item").Value.ToString();

                        if (parentName.LastIndexOf("/") > -1)
                        {
                            parentName = parentName.Substring(0, parentName.LastIndexOf("/"));
                        }
                        StructureList.Add(new ExtendedStructureItem(Item.Attribute("Item").Value.ToString(), parentName, "dd", null));
                    }
                }

                //section
                var item2 = doc.Descendants("Item");
                foreach (var Item1 in item2)
                {
                    if (Item1.Attribute("Value") != null && Item1.Attribute("Value").Value.ToString() == "section")
                    {
                        string Id = Item1.Attribute("Item").Value.ToString();
                         if (Id.LastIndexOf("/") > -1)
                            {
                                Id = Id.Substring(Id.LastIndexOf("/") + 1);
                            }
                        string parentName;
                        if (Id.LastIndexOf("/") > -1)
                        {
                            parentName = Id.Substring(0, Id.LastIndexOf("/"));
                        }
                        else
                        { parentName = null; }
                                StructureList.Add(new ExtendedStructureItem(Id, parentName, "dd", null));
                            }
                        
                        //string shotId = Item1.Attribute("Id").Value.ToString();
                        //foreach (var Item11 in item2)
                        //{
                        //    if (Item11.Attribute("Id").Value.ToString() == shotId && Item11.Attribute("Type").Value.ToString() == "component")
                        //    {
                        //        string parentName = Item11.Attribute("Item").Value.ToString();
                        //        if (parentName.LastIndexOf("/") > -1)
                        //        {
                        //            parentName = parentName.Substring(0, parentName.LastIndexOf("/"));
                        //        }
                        //        StructureList.Add(new ExtendedStructureItem(Item11.Attribute("Item").Value.ToString(), parentName, "dd", null));
                        //    }
                        //}
                    }
                

                var item3 = doc.Descendants("Item");
                foreach (var Item33 in item3)
                {
                    if (Item33.Attribute("Value") != null && Item33.Attribute("Value").Value.ToString() == "element")
                    {
                        string Id = Item33.Attribute("Item").Value.ToString();
                         if (Id.LastIndexOf("/") > -1)
                            {
                                Id = Id.Substring(Id.LastIndexOf("/") + 1);
                            }
                        string parentName;
                        if (Id.LastIndexOf("/") > -1)
                        {
                            parentName = Id.Substring(0, Id.LastIndexOf("/"));
                        }
                        else
                        { parentName = null; }
                                StructureList.Add(new ExtendedStructureItem(Id, parentName, "dd", null));
                            }
                        }
                    }
                }
            



        static Stream GetResourceStream(string resourceFile)
        {
            Uri uri = new Uri(resourceFile, UriKind.RelativeOrAbsolute);
            StreamResourceInfo info = Application.GetResourceStream(uri);
            if (info == null || info.Stream == null)
                throw new ApplicationException("Missing resource file: " + resourceFile);
            return info.Stream;
        }
        #region old- part load from xml
        /* public List<Model> LoadFileData(string DataFile)
        {
            using (Stream stream = GetResourceStream(DataFile))
            using (XmlReader xmlRdr = new XmlTextReader(stream))
                return (from customerElem in XDocument.Load(xmlRdr).Element("Zone").Elements("section")
                        select new Model((string)customerElem.Attribute("lastName"))).ToList();
        }

       

        //public ObservableCollection<Model> sectionData
        //{
        //    set
        //    {
        //        sectionViewData = value;
        //        OnPropertyChanged("sectionData");
        //    }
        //    get { return sectionViewData; }
        //}

        List<Model> LoadSectionData(string SectionData)
        {
            using (Stream stream = GetResourceStream2(SectionData))
            using (XmlReader xmlRdr = new XmlTextReader(stream))
                return (from customerElem in XDocument.Load(xmlRdr).Element("zones").Elements("zone")
                        select new Model((string)customerElem.Attribute("Section"))).ToList();
        }

        static Stream GetResourceStream2(string resourceFile2)
        {
            Uri uri = new Uri(resourceFile2, UriKind.RelativeOrAbsolute);
            StreamResourceInfo info = Application.GetResourceStream(uri);
            if (info == null || info.Stream == null)
                throw new ApplicationException("Missing resource file: " + resourceFile2);
            return info.Stream;
        }
        public ObservableCollection<Dictionary<string, object>> Errors
        {
            get { return errors; }
            set { errors = value; OnPropertyChanged("Errors"); }
        }

        public valuepair Index
        {
            get { return _index; }
            set { _index = value; OnPropertyChanged("Index"); }
        }*/
        #endregion



        //return a static instance of DataDidpacher
        public static DataDispacher Instance
        {
            get
            {
                if (instance == null)
                {
                    DataDispacher.instance = new DataDispacher();
                }
                return instance;
            }
        }



        //Return the ErrorList
        public ObservableCollection<CStructureItem> LoadFSCErrors(CStructureItem item)
        {
            string level = item.IntegrationLevel;
            if (item != null)
            {
               var index= new ObservableCollection<CStructureItem>((from error in errors
                                                                 where
                                                                     TailorID(error.ParentId, level) == item.Id  
                                                                    select error).ToList());
               return index;
            }
            else return errors;
        }

        public string TailorID(string ParentID,string level)
        {

            switch (level)
            {
                case "zone":
                    if (ParentID.LastIndexOf("/") > -1)
                    {
                        ParentID = ParentID.Substring(0, ParentID.LastIndexOf("/"));
                    }
                    break;
                case "group":
                    if (ParentID.LastIndexOf("/") > -1)
                    {
                        ParentID = ParentID.Substring(0, ParentID.LastIndexOf("/"));
                    }
                    break;
            }

            return ParentID;
        }

        //Get structure list base on and parentId
        //Give null to type and ParentId if the list are not very applicable.
        public ObservableCollection<ExtendedStructureItem> LoadFSCStructureItems(string ParentId)
        {
            if (ParentId != null)
                return new ObservableCollection<ExtendedStructureItem>((from item in StructureList
                                                                        where item.ParentId == ParentId
                                                                        select item).ToList());
            else return null;
        }

        public void HandleNewComponentsErrors(List<CStructureItem> errorsList)
        {
            errors = new ObservableCollection<CStructureItem>(errorsList);
            errorUpdateEvent();
        }
    }
}